package manager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;

import util.HibernateUtil;
import domain.DdBagkeysDAO;
import domain.ErrorReasonsDAO;
import exception.IBToolsException;

@SuppressWarnings({"unchecked","rawtypes"})
public class MapManager {

	private static Map<Long, String> bagKeyMap = null;
	private static Map<String, String> errorReasonMap = null;
	
	public static void initErrorReasonMap() throws IBToolsException{
		
		Session session =  HibernateUtil.getDEVSession();
        Transaction tx = null;
        
        try {
			tx = HibernateUtil.beginDEVTransaction(session);
		
			Criteria criteria = session.createCriteria(ErrorReasonsDAO.class);
			
			if(errorReasonMap == null){
				errorReasonMap = new HashMap<String, String>(0);
			}
			else {
				errorReasonMap.clear();
			}
			
			List<ErrorReasonsDAO> errorReasons = (List<ErrorReasonsDAO>) 
					criteria.setProjection(
							Projections.projectionList()
							  .add(Projections.property("errorType"), "errorType")
							  .add(Projections.property("reason"), "reason")
							)
							.setResultTransformer(Transformers.aliasToBean(ErrorReasonsDAO.class))
							.list();
			
			for (ErrorReasonsDAO errorReasonsDAO : errorReasons) {
				errorReasonMap.put(errorReasonsDAO.getErrorType(), errorReasonsDAO.getReason());
			}
			
			tx.commit();
		} catch (HibernateException e) {
			tx.rollback();
			throw e;
		}
	}

	public static void loadMapWithInBagKeys(List<Long> bagKeyInList) throws IBToolsException{

		if(bagKeyInList == null || bagKeyInList.size() == 0)
			return;
		if(bagKeyMap == null){
			bagKeyMap = new HashMap<Long, String>(0);
		}
    	Session session = HibernateUtil.getDEVSession();
        Transaction tx = null;
        
        try {
			tx = HibernateUtil.beginDEVTransaction(session);
			Criteria criteria = session.createCriteria(DdBagkeysDAO.class)
					.add(Restrictions.in("bagkeyvalue", bagKeyInList));
			List bagKeys = criteria.setProjection(
					Projections.projectionList()
					  .add(Projections.property("bagkeyvalue"))
					  .add(Projections.property("bagkeyname")))
					  .list();
			tx.commit();

			for (Object o : bagKeys) {
				Object[] param = (Object[]) o;
				bagKeyMap.put((Long)param[0], (String)param[1]);
			}
		} catch (HibernateException e) {
			tx.rollback();
			throw e;
		}
	}
	
	private static String getBagKeyFromDB(Long key) throws IBToolsException{

    	Session session = HibernateUtil.getDEVSession();
    	Transaction tx = null;
    	String sonuc = null;
    	try {
			tx = HibernateUtil.beginDEVTransaction(session);
			Criteria criteria = session.createCriteria(DdBagkeysDAO.class);
			
			List bagKeys = criteria
					.add(Restrictions.eq("bagkeyvalue", key))
					.setProjection(
							Projections.projectionList()
							.add(Projections.property("bagkeyname"))
			).list();
			sonuc = (String)bagKeys.get(0);
			tx.commit();
			
		} catch (HibernateException e) {
			tx.rollback();
			throw e;
		}

		
		return sonuc;
	}

	public static List<Long> addToBagKeyInList(List<Long> bagKeyInList, String stringValue) throws IBToolsException{
		try {
			Long value = new Long(stringValue);
			if(value != null && MapManager.getBagKeyNameOnlyFromMap(value) == null){
				bagKeyInList.add(value);
			}
		} catch (NumberFormatException e) {}
		return bagKeyInList;
	}
	
	public static String getBagKeyNameOnlyFromMap(Long key) throws IBToolsException{
		String bagKey = null;
		if(bagKeyMap != null){
			bagKey = bagKeyMap.get(key);
		}
		if(key == -1){
			bagKey = "";
		}
		return bagKey;
	}
	
	public static String getBagKeyNameFromMapThenDB(Long key) throws IBToolsException{
		String bagKey = getBagKeyNameOnlyFromMap(key);
		if(bagKey == null){
			bagKey = getBagKeyFromDB(key);
		}
		return bagKey;
	}
	
	public static String getErrorReason(String errorType){
		return errorReasonMap.get(errorType);
	}
}
